﻿using Coldairarrow.Entity.Base;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.IT;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_RepairOrderApplyBusiness : BaseBusiness<Base_RepairOrderApply>, IPB_RepairOrderApplyBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        public PB_RepairOrderApplyBusiness(IDbAccessor db, IOperator @operator)
            : base(db)
        {
            _operator = @operator;
        }

        #region 外部接口

        public async Task<PageResult<Base_RepairOrderApply>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<Base_RepairOrderApply>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<Base_RepairOrderApply, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<Base_RepairOrderApply> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(Base_RepairOrderApply data)
        {
            //生成随机工单号
          var a=  Guid.NewGuid().ToString("n");
                data.Deleted = false;
                data.ApplicationDate = DateTime.Now;
                data.States = 0;
                data.RepairOrderNo = a;
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(Base_RepairOrderApply data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        public  async Task<PageResult<Base_RepairOrderApplyDTO>> GetRepairOrderApplyList(PageInput<PB_ScheduleDetailConditionDTO> input)
        {
            var where = LinqHelper.True<Base_RepairOrderApplyDTO>();
            var search = input.Search;
            Expression<Func<Base_RepairOrderApply, Base_User, Entity.Base.Base_Device,Base_User, Base_RepairOrderApplyDTO>> select = (a,b,c,d) => new Base_RepairOrderApplyDTO
            {
               ApplicantName=b.RealName,
               DeviceName=c.Name,
               MaintenanceApproverName=d.RealName,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_User>() on a.Applicant equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_Device>() on a.DeviceId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_User>() on a.MaintenanceApprover equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    select @select.Invoke(a,b,c,d);
            if (!input.Search.Keyword.IsNullOrEmpty()) {
                q = q.Where(m=>m.DeviceName.Contains(input.Search.Keyword));
            }
            if (!input.Search.Name.IsNullOrEmpty()) {
                q = q.Where(m=>m.ApplicantName.Contains(input.Search.Name));
            }
            if (!search.StartDate.IsNullOrEmpty() && !search.EndDate.IsNullOrEmpty())
            {
                DateTime StartDate = Convert.ToDateTime(Convert.ToDateTime(search.StartDate).Date.ToString());
                DateTime EndDate = Convert.ToDateTime(Convert.ToDateTime(search.EndDate).Date.ToString()).AddDays(1).AddSeconds(-1);
                q = q.Where(x => StartDate <= x.ApplicationDate && x.ApplicationDate <= EndDate);
            }
            return await q.Where(where).GetPageResultAsync(input);
        }

        public  async Task<Base_RepairOrderApplyListInfo> GetRepairOrderApplyListInfo(string ApplyId)
        {

            Expression<Func<Base_RepairOrderDetails, PB_Material, Base_RepairOrderDetailsDto>> select = (a, b) => new Base_RepairOrderDetailsDto
            {
                Name = b.Name,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<Base_RepairOrderDetails>().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select @select.Invoke(a, b);

            var K = Db.GetIQueryable<Base_RepairOrder>();
            Base_RepairOrderApplyListInfo listData = new Base_RepairOrderApplyListInfo();
            var Applicationdata = Db.GetIQueryable<Base_RepairOrderApply>().Where(m=>m.Id==ApplyId).FirstOrDefault();
            List<Base_RepairOrder> MainData = await K.Where(x => x.Parentid == ApplyId).ToListAsync();


            #region 组装维修工单主表数据
            listData.MainData = MainData;
            #endregion

            #region 组装明细数据
            foreach (var aa in MainData)
            {
                List<Base_RepairOrderDetailsDto> SubDataList = await q.Where(x => x.ParentId == aa.Id).ToListAsync();
                listData.SubData = SubDataList;
            }
           
            #endregion
            return listData;
           
        }

        public async Task<Base_RepairOrderList> GetRepairOrderList(string ApplyId)
        {
            Expression<Func<Base_RepairOrderDetails, PB_Material, IT_LocalMaterial,PB_Location, Base_RepairOrderDetailsDto>> select = (a, b,c,d) => new Base_RepairOrderDetailsDto
            {
                Code=b.Code,
                Spce = b.Spec,
                Name = b.Name,
                Inventoryquantity = c.Nums_N + c.Nums_O,
                Position=d.PB_StorArea.Name+"/"+d.PB_Rack.Name+"/"+d.Name,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<Base_RepairOrderDetails>().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<IT_LocalMaterial>() on a.LocalMaterialId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<PB_Location>() on c.LocalId equals d.Id into cd
                    from d in cd.DefaultIfEmpty()
                    select @select.Invoke(a, b,c,d);
            var K = Db.GetIQueryable<Base_RepairOrder>().Where(m=>m.Id==ApplyId).FirstOrDefault();
            List<Base_RepairOrderDetailsDto> SubDataList = await q.Where(x => x.ParentId == K.Id).ToListAsync();
            Base_RepairOrderList listData = new Base_RepairOrderList();
            listData.Id = K.Id;
            listData.CreateTime = K.CreateTime;
            listData.Parentid = K.Parentid;
            listData.UserId = K.UserId;
            listData.CompletionTime = K.CompletionTime;
            listData.Type = K.Type;
            listData.MaintenancePrice = K.MaintenancePrice;
            listData.FaultAnalysis = K.FaultAnalysis;
            listData.MaintenanceLevel = K.MaintenanceLevel;
            listData.DeviceId = K.DeviceId;
            #region 组装维修工单主表数据
            listData.SubData = SubDataList;
            #endregion

            #region 组装明细数据
          

            #endregion
            return listData;
        }

        /// <summary>
        /// 打印维修工单号
        /// </summary>
        /// <param name="ApplyId"></param>
        /// <returns></returns>
        public async Task<Base_RepairOrderPrint> Base_RepairOrderPrint(string ApplyId)
        {

            Expression<Func<Base_RepairOrder, Base_RepairOrderApply,Base_User,Base_User,Base_Device,Base_EnumItem,Base_EnumItem, Base_RepairOrderPrint>> selects = (a, b,c,d,e,f,g) => new Base_RepairOrderPrint
            {
                Id=a.Id,
               Applicant=c.RealName,
                ApplicationDate=b.ApplicationDate,
                FaultDescription=b.FaultDescription,
                UserId=d.RealName,
                CompletionTime=a.CompletionTime,
                FaultAnalysis=a.FaultAnalysis,
                MaintenancePrice=a.MaintenancePrice,
                DeviceId=e.Name,
                QrCode=a.QrCode,
                ParentId=b.Id,
                Spec=e.Spec,
                Code=e.Code,
                Type=f.Name,
                MaintenanceLevel=g.Name,
            };
            selects = selects.BuildExtendSelectExpre();
            var main = from a in Db.GetIQueryable<Base_RepairOrder>().AsExpandable()
                    join b in Db.GetIQueryable<Base_RepairOrderApply>() on a.Parentid equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_User>() on b.Applicant equals c.Id into bc
                    from c in bc.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_User>() on a.UserId equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    join e in Db.GetIQueryable<Base_Device>() on a.DeviceId equals e.Id into ae
                    from e in ae.DefaultIfEmpty()
                    join f in Db.GetIQueryable<Base_EnumItem>() on a.Type equals f.Code into af
                    from f in af.DefaultIfEmpty()
                    join g in Db.GetIQueryable<Base_EnumItem>() on a.MaintenanceLevel equals g.Code into ag
                    from g in ag.DefaultIfEmpty()
                       select selects.Invoke(a, b, c,d,e,f,g);
            var   MAIN = await main.Where(x => x.ParentId == ApplyId).FirstOrDefaultAsync();

            Expression<Func<Base_RepairOrderDetails, PB_Material, IT_LocalMaterial, Base_RepairOrderDetailsDto>> select = (a, b, c) => new Base_RepairOrderDetailsDto
            {
                Code=b.Code,
                Spce = b.Spec,
                Name = b.Name,
                Inventoryquantity = c.Nums_N + c.Nums_O,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<Base_RepairOrderDetails>().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<IT_LocalMaterial>() on a.LocalMaterialId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    select @select.Invoke(a, b, c);
            var K = Db.GetIQueryable<Base_RepairOrder>().Where(m => m.Id == ApplyId).FirstOrDefault();
            List<Base_RepairOrderDetailsDto> SubDataList = await q.Where(x => x.ParentId == K.Id).ToListAsync();
         Base_RepairOrderPrint listData = new Base_RepairOrderPrint();
            listData.SubData = SubDataList;
            listData.Id = MAIN.Id;
            listData.Applicant = MAIN.Applicant;
            listData.ApplicationDate = MAIN.ApplicationDate;
            listData.FaultDescription = MAIN.FaultDescription;
            listData.UserId = MAIN.UserId;
            listData.CompletionTime = MAIN.CompletionTime;
            listData.FaultAnalysis = MAIN.FaultAnalysis;
            listData.MaintenancePrice = MAIN.MaintenancePrice;
            listData.DeviceId = MAIN.DeviceId;
            listData.QrCode = MAIN.QrCode;
            listData.ParentId = MAIN.ParentId;
            listData.Code = MAIN.Code;
            listData.Spec = MAIN.Spec;
            listData.Type = MAIN.Type;
            listData.MaintenanceLevel = MAIN.MaintenanceLevel;
            return listData;
        }

        /// <summary>
        /// 审核维修申请单
        /// </summary>
        /// <param name="ApplyId"></param>
        /// <returns></returns>
        public async Task ToExamineRepairOrderApply(string ApplyId)
        {
            
            string sqlMain = @" update Base_RepairOrderApply set `States`=2 where Id='" + ApplyId + "' ";
            await ExecuteSqlAsync(sqlMain);
        }

        public async Task <List<Base_EnumItem>> RepairOrderApplyType()
        {
            var q = Db.GetIQueryable<Base_EnumItem>().Where(x=>x.EnumCode== "MaintenanceLevel");
            return await q.ToListAsync();
        }

        /// <summary>
        /// 通过设备获取维修记录
        /// </summary>
        /// <param name="input"></param>
        /// <param name="DeviceId"></param>
        /// <returns></returns>
        public async Task<PageResult<Base_RepairOrderApplyDTO>> GetRepairOrderDeviceId(PageInput<ConditionDTO> input, string DeviceId)
        {
           
            Expression<Func<Base_RepairOrderApply, Base_User, Entity.Base.Base_Device, Base_User, Base_RepairOrderApplyDTO>> select = (a, b, c, d) => new Base_RepairOrderApplyDTO
            {
                ApplicantName = b.RealName,
                DeviceName = c.Name,
                MaintenanceApproverName = d.RealName,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_User>() on a.Applicant equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_Device>() on a.DeviceId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_User>() on a.MaintenanceApprover equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    select @select.Invoke(a, b, c, d);
            q = q.Where(m=>m.DeviceId==DeviceId);
            return await q.GetPageResultAsync(input);
        }

        /// <summary>
        /// pc保存设备维修记录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task EquipmentPatrolAdd(Base_RepairOrderMainAdd data)
        {
            //创建设备维修申请实体
            string Id = IdHelper.GetId();
            Base_RepairOrderApply base_RepairOrderApply = new Base_RepairOrderApply();
            base_RepairOrderApply.Id = Id;
            base_RepairOrderApply.Applicant = _operator.UserId;
            base_RepairOrderApply.ApplicationDate = data.ApplicationDate;
            base_RepairOrderApply.DeviceId = data.DeviceId;
            base_RepairOrderApply.FaultDescription = data.FaultDescription;
            base_RepairOrderApply.States = 1;
            base_RepairOrderApply.MaintenanceApprover = "";
            base_RepairOrderApply.CreateTime = DateTime.Now;
            base_RepairOrderApply.CreatorId =_operator.UserId;
            base_RepairOrderApply.Deleted = false;
            base_RepairOrderApply.RepairOrderNo = Id;//维修单号
            base_RepairOrderApply.Type = data.Type;//故障类别
            //创建维修工单主表实体
            Base_RepairOrder base_RepairOrder = new Base_RepairOrder();
            base_RepairOrder.Id = Id;
            base_RepairOrder.Parentid = Id;
            base_RepairOrder.UserId = data.UserId;
            base_RepairOrder.CompletionTime = data.CompletionTime;
            base_RepairOrder.Type = data.Type;
            base_RepairOrder.MaintenancePrice = data.MaintenancePrice;
            base_RepairOrder.QrCode = base_RepairOrderCode + "," + Id;
            base_RepairOrder.CreateTime = DateTime.Now;
            base_RepairOrder.CreatorId = _operator.UserId;
            base_RepairOrder.Deleted = false;
            base_RepairOrder.MaintenanceLevel = data.MaintenanceLevel;
            base_RepairOrder.DeviceId = data.DeviceId;
            //创建维修订单明细数据
            List<Base_RepairOrderDetails> base_RepairOrderDetailslist = new List<Base_RepairOrderDetails>();
            foreach (var item in data.SubData) {
                string detailsid = IdHelper.GetId();
                Base_RepairOrderDetails base_RepairOrderDetails = new Base_RepairOrderDetails();
                base_RepairOrderDetails.Id = detailsid;
                base_RepairOrderDetails.ParentId = Id;
                base_RepairOrderDetails.MaterialId = item.MaterialId;
                base_RepairOrderDetails.Nums = item.Nums;
                base_RepairOrderDetails.CreateTime = DateTime.Now;
                base_RepairOrderDetails.CreatorId =_operator.UserId;
                base_RepairOrderDetails.Deleted = false;
                base_RepairOrderDetails.QrCode = base_RepairOrderDetailsCode + "," + detailsid;
                base_RepairOrderDetails.LocalMaterialId = item.LocalMaterialId;
                base_RepairOrderDetailslist.Add(base_RepairOrderDetails);
            }
            await Db.InsertAsync(base_RepairOrderApply);
            await Db.InsertAsync(base_RepairOrder);
            await Db.InsertAsync(base_RepairOrderDetailslist);
        }

        #endregion

        #region 私有成员

        #endregion
    }
}